﻿using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace DH.MQ
{
    public class RabbitMQInit
    {
        //创建一个静态的只读对象(用于下面的加锁)
        private static readonly object SyncRoot = new object();
        public IConnection MyProperty { get; set; }

        #region 队列工厂的基础属性字段,静态构造方法
        private static readonly RabbitMQInit _instance;
        
         
  
          //静态构造函数，在类初始化的时候执行，不用加 public / private 没有意义,因为这个是由.net自动来调用      
          static RabbitMQInit()
          {
            _instance = new RabbitMQInit();
              
          }
          private static RabbitMQInit Instance
          {
              get { return _instance; }
          }
          
          #endregion
  
          #region 工厂单例
          private static RabbitMQInit _shareInstance;
  
          public static RabbitMQInit GetCurrentRabbitMQ()
          {
              if (_shareInstance == null)
                  lock (SyncRoot)
                  {
                      _shareInstance = new RabbitMQInit();
                  }
              return _shareInstance;
          }
        #endregion

        public  XMLConfig config = null;

        public  IConnection CreateConnection()
        {
            const ushort heartbeat = 60;//心跳

            if (config == null)
            {
                config = (XMLConfig)new XMlSettingProvider().GetCurrentSetting();
            }
            var fact = new ConnectionFactory()
            {
                HostName = config.VHost,
                UserName = config.User,
                Password = config.PWD,
                RequestedHeartbeat = heartbeat,
                AutomaticRecoveryEnabled = true //自动重连
            };

            return fact.CreateConnection();
        }
        public  IModel CreateChannel(IConnection connection,int time=0)
        {
            var channel = connection.CreateModel();

            //exchange的4种模式：direct fanout headers topic
            channel.ExchangeDeclare(exchange: config.exchanges[0].Name,
                                       type: config.Type, durable: config.IsDurability,autoDelete:true,arguments:null);


                //初始化所有Queue
                foreach (Queue currentQueue in RabbitMQInit.GetCurrentRabbitMQ().config.exchanges[0].queues.ToList<Queue>())
                {

                    channel.QueueDeclare(currentQueue.Name, true, false, false, null);
                    //binding
                    channel.QueueBind(currentQueue.Name, RabbitMQInit.GetCurrentRabbitMQ().config.exchanges[0].Name, currentQueue.RoutingKey);
                channel.QueueBind(currentQueue.Name, RabbitMQInit.GetCurrentRabbitMQ().config.exchanges[0].Name, currentQueue.Name);
                if (time!=0)
                {
                    //初始化对应的延迟队列
                    Dictionary<String, Object> arguments = new Dictionary<String, Object>();
                    arguments.Add("x-dead-letter-exchange", RabbitMQInit.GetCurrentRabbitMQ().config.exchanges[0].Name);
                    arguments.Add("x-dead-letter-routing-key", currentQueue.Name);
                    arguments.Add("x-expires", time*1000+180000);//设置
                    channel.QueueDeclare("delay." +time+"."+ currentQueue.Name, true, false, false, arguments);
                    channel.QueueBind("delay." + time + "." + currentQueue.Name, RabbitMQInit.GetCurrentRabbitMQ().config.exchanges[0].Name, "delay." + time + "." + currentQueue.RoutingKey);
                }
               
            }
            return channel;
        }


    }
}
